package org.xxpay.pay.channel.haitian;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import org.springframework.stereotype.Service;
import org.xxpay.common.http.HttpRequestTemplate;
import org.xxpay.common.util.DateUtils;
import org.xxpay.common.util.sign.SignUtils;
import org.xxpay.common.util.str.StringUtils;
import org.xxpay.core.common.constant.PayConstant;
import org.xxpay.core.common.util.AmountUtil;
import org.xxpay.core.entity.PayOrder;
import org.xxpay.pay.channel.BasePayment;

import java.util.Date;
import java.util.Map;

@Service
public class HaitianPaymentService extends BasePayment {

    private final static String logPrefix = "【海天】";
    @Override
    public String getChannelName() {
        return HaitianConfig.CHANNEL_NAME;
    }

    /**
     * 查询订单
     * @param payOrder
     * @return
     */
    @Override
    public JSONObject query(PayOrder payOrder){

        HaitianConfig config = new HaitianConfig(getPayParam(payOrder));
        String payOrderId = payOrder.getPayOrderId();
        _log.info("{}开始查询通道订单,payOrderId={}", logPrefix, payOrderId);
        Map<String, Object> params = Maps.newHashMap();
        params.put("version",HaitianConfig.VIL_VERSION_VLAUE);
        params.put("merchant_number", config.getAppId());
        params.put("order_id", payOrder.getPayOrderId());
        params.put("sign", getSign(params, config.getPrivateKey()));
        _log.info("{}查询通道订单请求数据:{}", getChannelName(), JSON.toJSONString(params));
        HttpRequestTemplate requestTemplate = new HttpRequestTemplate(null);
        JSONObject origin = requestTemplate.postForObject(getReqUrl(config.getRequestUrl(),HaitianConfig.REQ_QUERY_Fixx), params, JSONObject.class);
        _log.info("{}智付查单同步请求响应参数：{}", logPrefix, origin.toJSONString());
        // 响应对象
        JSONObject retObj = new JSONObject();
        if(StringUtils.equals(origin.getString("code"),"1")){
            JSONObject backData = JSONObject.parseObject(origin.getString("data"));
            // 订单支付状态：2-为已⽀支付，其它未⽀支付
            //已支付
            if(StringUtils.equals(backData.getString("status"),"2")){
                retObj.put("status", 2);
            }else{
                // 支付中
                retObj.put("status", 1);
            }
            retObj.put(PayConstant.RETURN_PARAM_RETCODE, PayConstant.RETURN_VALUE_SUCCESS);
            retObj.put("channelOrderNo", backData.getString("order_id"));
            retObj.put("channelObj", backData);
            return retObj;
        }
        retObj.put(PayConstant.RETURN_PARAM_RETCODE, PayConstant.RETURN_VALUE_FAIL);
        retObj.put(PayConstant.RESULT_PARAM_ERRDES, origin.getString("msg"));
        return retObj;
    }

    /**
     * 支付下单
     * @param payOrder
     * @return
     */
    @Override
    public JSONObject pay(PayOrder payOrder){
        String channelId = payOrder.getChannelId();
        JSONObject retObj;
        switch (channelId) {
            case HaitianConfig.CHANMEL_NAME_HAITIAN_WXPAY:
                retObj = doOrderReq(payOrder,"4",HaitianConfig.REQ_PAY_2_3_Fixx);
                break;
            case HaitianConfig.CHANMEL_NAME_HAITIAN_WXPAY_SCAN:
                retObj = doOrderReq(payOrder,"3",HaitianConfig.REQ_PAY_2_3_Fixx);
                break;
            case HaitianConfig.CHANMEL_NAME_HAITIAN_ALI_QR:
                retObj = doOrderReq(payOrder,"1",HaitianConfig.REQ_PAY_2_4_Fixx);
                break;
                default:
                    retObj = buildRetObj(PayConstant.RETURN_VALUE_FAIL, "不支持的渠道[channelId="+channelId+"]");
                    break;
        }
        return retObj;
    }

    //下单实现
    private JSONObject doOrderReq(PayOrder payOrder,String payType,String payFixx){
        HaitianConfig config = new HaitianConfig(getPayParam(payOrder));
        // 请求参数
        Map<String,Object> params = Maps.newHashMap();
        setParams(payOrder,config,payType,params);
        _log.info("{}请求数据:{}", getChannelName(), JSON.toJSONString(params));
        // 将订单改为支付中
        rpcCommonService.rpcPayOrderService.updateStatus4Ing(payOrder.getPayOrderId(), null);
        HttpRequestTemplate requestTemplate = new HttpRequestTemplate(null);
        String  result = requestTemplate.postForObject(getReqUrl(config.getRequestUrl(),payFixx), params, String.class);
        _log.info("{}响应参数：{}", logPrefix, result);
        JSONObject retObj = new JSONObject();
        if(isJson(result)){
            JSONObject origin = JSONObject.parseObject(result);
            retObj.put(PayConstant.RETURN_PARAM_RETCODE, PayConstant.RETURN_VALUE_FAIL);
            retObj.put(PayConstant.RESULT_PARAM_ERRDES, origin.getString("msg"));
            return retObj;
        }
        return buildPayResultOfForm(retObj, payOrder,result);
    }

    //设置请求参数
    private void setParams(PayOrder payOrder, HaitianConfig config,String type,Map<String,Object> params){

        params.put("version", HaitianConfig.VIL_VERSION_VLAUE);
        params.put("merchant_number", config.getAppId());
        params.put("cash", AmountUtil.convertCent2Dollar(String.valueOf(payOrder.getAmount())));
        params.put("server_url", payConfig.getNotifyTransUrl(getChannelName()));
        params.put("brower_url", payOrder.getReturnUrl());
        params.put("order_id", payOrder.getPayOrderId());
        params.put("order_time", DateUtils.timestamp(new Date()));
        params.put("pay_type", type);
        params.put("sign", getSign(params, config.getPrivateKey()));
    }

    //获取签名
    private String getSign(Map<String,Object> params,String key){
        String signTxt = SignUtils.parameterText(params);
        _log.info("{}海天支付签名字符串：{}", logPrefix, signTxt);
        String sign = SignUtils.MD5.createSign(signTxt, "&key="+key, SignUtils.CHARSET_UTF8);
        return sign;
    }

    //判断字符串是否为json格式
    private static boolean isJson(String content) {
        try {
            JSONObject.parseObject(content);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}
